<!-- 好友请求组件 -->
<template>
    <div class="friend-req">
        <div class="title">新的朋友</div>
        <div class="content" @click="isShow=true" >
            <el-badge :value="toBeAgreedNum" :max="10" :hidden="toBeAgreedNum === 0">
                <div class="icon-warp">
                    <i  class="iconfont icon-zhucetianjiahaoyou icon"/>
                </div>
            </el-badge>
            <div class="text">
                新的朋友
            </div>
        </div>
        <el-dialog class="dialog" title="好友请求" :visible.sync="isShow" :before-close="onBeforeClose" >
            <div class="req-content scroll-bar-v">
                <!-- 一条请求消息 -->
                <div class="req-warp" v-for="item in requestList" :key="item.id">
                    <el-popover placement="top-start" width="330" trigger="click">
                        <user-info-com :user="item.requestUser" />
                        <div class="avatar" slot="reference">
                            <el-image fit="cover" :src="item.requestUser.avatar" lazy/>
                        </div>
                    </el-popover>
                    <div class="info">
                        <div class="header">
                            <div class="name">{{item.requestUser.name}}</div>
                            <div class="date">{{formatTime(item.requestTime)}}</div>
                        </div>
                        <el-tooltip effect="dark" :open-delay="1000" :content="item.describe" placement="bottom-start">
                            <div class="describe">{{item.describe}}</div>
                        </el-tooltip>
                    </div>
                    <!-- 未同意，待同意 -->
                    <div v-if="item.state === 0">
                        <div class="option">
                            <div class="agree-btn btn" @click="updateRequestState(item.id,1)">同意</div>
                                <!-- 弹出框，需要用户输入拒绝理由 -->
                                <el-popover placement="bottom" width="200px" v-model="item.confuse.isShow">
                                    <div class="confuse-popover">
                                        <p class="header">请输入您的拒绝理由:</p>
                                        <input type="text" v-model="item.confuse.value">
                                        <div class="btn">
                                            <span @click="()=>{updateRequestState(item.id,2,item.confuse.value);item.confuse.isShow=false;}">
                                                确定
                                            </span>
                                        </div>
                                    </div>
                                    <div slot="reference" class="refuse-btn btn">拒绝</div>
                                </el-popover>
                        </div>
                    </div>
                    <!-- 已同意 -->
                    <div v-else-if="item.state === 1">
                        <div class="agree">已同意</div>
                    </div>
                    <!-- 已拒绝 -->
                    <div v-else>
                        <div class="confuse">已拒绝{{item.refuseMsg==''?'':': '+item.refuseMsg}}</div>
                    </div>
                </div>
            </div>
            <!-- 工具栏 -->
            <div class="tool-bar">
                <div class="opt">
                    <div class="agree">
                        <el-link type="primary" @click="batchOptions(true)" icon="el-icon-check">全部同意</el-link>
                    </div>
                    <div class="confuse">
                        <el-link type="danger" @click="batchOptions(false)" icon="el-icon-close">全部拒绝</el-link>
                    </div>
                </div>
                <div class="filter">
                    <el-checkbox-group v-model="filterArr" @change="onFilterChange">
                        <el-checkbox label="0">待同意</el-checkbox>
                        <el-checkbox label="1">已同意</el-checkbox>
                        <el-checkbox label="2">已拒绝</el-checkbox>
                    </el-checkbox-group>
                </div>
            </div>
        </el-dialog>
    </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import UserInfoCom from '../components/UserInfoCom.vue'
import io from '../socket'
import axios from 'axios'
import moment from 'moment'

@Component({
    components:{
        UserInfoCom
    }
})
export default class FriendRequest extends Vue {

    $message:any
    $notify:any
    $store:any

    // 是否显示弹窗
    public isShow:boolean = false

    // 好友申请列表(源数据列表)
    public requestSourceList:any[] = []

    // 显示数据的申请列表(可能由于过滤，失去部分信息)
    public requestList:any[] = []

    // 过滤条件列表
    public filterArr:string[] = ['0','1','2']

    beforeMount() {
        // 有用户发来好友申请
        io.socket?.on('onFriendRequest', this.onFriendRequest)
        // 注册新朋友申请回复事件(拒绝2或同意)
        io.socket?.on('onFriendRequestResponse', this.onFriendRequestResponse)
        // 获取好友请求列表
        this.getFriendRequestList()
    }

    // 有用户发来好友申请
    private onFriendRequest(msg:string){
        const req = JSON.parse(msg)
        console.log(req)
        const index = this.requestSourceList.findIndex(request=>request.id===req.id)
        if(index >= 0){
            this.requestSourceList.splice(index, 1)
        }
        this.requestSourceList.unshift(req)
        this.handleRequestList()
        this.onFilterChange()
        this.$notify({
            title: '好友申请',
            type: 'info',
            message: `用户:${req.requestUser.name},发来了一条好友申请,描述:"${req.describe}"。`
        })
    }

    
    // 有新朋友申请另一方做出回应的消息
    private onFriendRequestResponse(msg:string){
        const data = JSON.parse(msg)
        if(data.state === 2){
            // 拒绝
            this.$notify({
                title: '好友申请信息反馈',
                type: 'warning',
                duration: 0,
                message: `用户:"${data.targetUser.name}",拒绝了您的好友请求,理由:"${data.reason}"。`
            })
        }else{
            // 允许
            data.data.msgList = []
            this.$store.state.friends.push(data.data);
            this.$notify.success(`您和"${data.data.remark}"已经成为好友了，快来聊天吧!`);
        }
    }

    // 获取好友请求列表
    private getFriendRequestList(){
        axios.get('/api/v1/friend/request')
            .then(res=>{
               if(res.data.code===200){
                   this.requestSourceList = res.data.data
                   this.handleRequestList()
                   this.requestList = []
                   this.requestList.push(...this.requestSourceList)
               }else{
                   this.$message.error(res.data.msg)
               }
            })
            .catch(err=>{
                this.$message.error("获取好友请求信息失败:" + err)
            })
    }

    // 处理请求列表中的数据，挂载一些属性至其身上
    private handleRequestList(){
        this.requestSourceList.forEach(req =>{
            // 挂载，拒绝信息
            if(typeof req.showDel === 'undefined'){
                req['confuse'] = {
                    isShow: false, // 是否显示拒绝理由弹出窗
                    value: ''      // 拒绝理由
                }
            }
        })
    }

    // 更新好友请求状态
    public updateRequestState(id:string, state:number, confuseMsg:string=''){
        const msg = state===2 ? '?msg=' + confuseMsg : '';
        axios.post(`/api/v1/friend/state/${id}/${state}${msg}`)
            .then(res=>{
                if(res.data.code===200){
                    const curReq = this.requestSourceList.filter(req=>req.id===id)[0]
                    curReq.state = state
                    curReq.refuseMsg = confuseMsg
                    // 重新过滤数据
                    this.onFilterChange()
                }else{
                    this.$message.error(res.data.msg);
                }
            })
            .catch(err=>{
                this.$message.error('更新信息失败:' + err);
            })
    }

    // 批量操作 isAgree是否全部同意，否则全部拒绝
    public batchOptions(isAgree:boolean){
        const state = isAgree ? 1 : 2;
        // 只操作过滤后的列表
        this.requestList.forEach(req=>{
            if(req.state === 0){
                this.updateRequestState(req.id,state)
            }
        })
    }

    // 窗口关闭前回调
    public onBeforeClose(){
        this.isShow = false
    }

    // 过滤条件发送改变事件
    public onFilterChange(){
        this.requestList = []
        this.requestSourceList.forEach(req=>{
            if(req.state === 0 && this.filterArr.includes('0')){
                this.requestList.push(req)
                return
            }
            if(req.state === 1 && this.filterArr.includes('1')){
                this.requestList.push(req)
                return
            }
            if(req.state === 2 && this.filterArr.includes('2')){
                this.requestList.push(req)
                return
            }
        })
    }

    // 获取所有待同意好友请求的个数
    get toBeAgreedNum(){
        let num = 0
        this.requestSourceList.forEach((r:any)=>{
            if(r.state === 0){
                num += 1
            }
        })
        return num
    }

    // 格式化消息事件
    public formatTime(date:string){
        moment.locale('zh-cn'); 
        return moment(date).format('YYYY-MM-DD HH:mm')
    }

}
</script>

<style lang="less" scoped>
@import '../css/iconfont.less';
@import '../css/index.less';
.friend-req{
    width: 100%;
    .title{
        font-size: 10px;
        color: #999999;
        padding: 10px;
    }
    .content{
        display: flex;
        align-items:center;
        padding: 10px;
        &:hover{
            background-color:#DEDBDA;
        }
        .icon-warp{
            width: 40px;
            height: 40px;
            background-color: #FA9D3B;
            display: flex;
            justify-content: center;
            align-items: center;
            border-radius: 2px;
            .icon{
                font-size: 25px;
                color: white;
            }
        }
        .text{
            font-size: 14px;
            margin-left: 10px;
        }
    }
    .dialog{
        /deep/  .el-dialog__body{
            padding: 10px;
        }
        .req-content{
            height: 50vh;
        }
        .req-warp {
            padding: 10px;
            display: flex;
            align-items: center;
            &:hover{
                background-color:#DEDBDA;
            }
            .avatar {
                height: 50px;
                width: 50px;
                border-radius: 5px;
                overflow: hidden;
                cursor: pointer;
                .el-image {
                    width: 100%;
                    height: 100%;
                }
            }
            .info {
                flex: 1;
                min-height: 50px;
                margin-left: 15px;
                display: flex;
                flex-direction: column;
                justify-content: space-around;
                overflow: hidden;
                .header{
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    .name {
                        font-size: 16px;
                        color: @theme-color;
                    }
                    .date{
                        color: #999999;
                        font-size: 10px;
                    }
                }
                
                .describe {
                    max-width: 100%;
                    color:black;
                    font-size: 12px;
                    white-space: nowrap;
                    text-overflow: ellipsis;
                    overflow: hidden;
                }
            }
            // 待同意按钮组
            .option {
                display: flex;
                margin-left: 10px;
                & .btn{
                    width: 80px;
                    height: 31px;
                    line-height: 31px;
                    border-radius: 3px;
                    color: white;
                    text-align: center;
                    border: 1px solid #FFF;
                    transition: all 0.5s;
                    cursor: pointer;
                }
                .agree-btn {
                    background-color: #1E6FFF;
                    border-color: #1E6FFF;
                    &:hover{
                        background-color: white;
                        color: #1E6FFF;
                    }
                }
                .refuse-btn {
                    background-color: red;
                    border-color: red;
                    margin-left: 10px;
                    &:hover{
                        background-color: white;
                        color: red;
                    }
                }
            }
            // 已经同意
            .agree{
                padding: 10px;
                color: #777;
            }
            // 已经拒绝
            .confuse{
                max-width: 150px;
                padding: 0px 10px;
                font-size: 12px;
                display: -webkit-box;
                -webkit-line-clamp: 3;
                -webkit-box-orient: vertical;
                overflow: hidden;
            }
        }
        .tool-bar{
            padding: 5px 0;
            border-top: 1px solid #DEDBDA;
            display: flex;
            align-items: center;
        }
        .opt{
            flex:1;
            display: flex;
            &>div{
                padding: 0 10px;
            }
        }
    }
}
.confuse-popover{
    .header{
        color: @theme-color;
        margin-bottom: 5px;
    }
    input{
        display: block;
        outline: none;
        font-size: 10px;
    }
    .btn{
        text-align: right;
        margin-top: 5px;
        span{
            display: inline-block;
            padding: 5px 15px;
            border-radius: 3px;
            background-color: @theme-color;
            border: 1px solid @theme-color;
            color: white;
            font-size: 12px;
            transition: all 0.5s;
            &:hover{
                background-color: white;
                color: @theme-color;
                cursor: pointer;
            }
        }
    }
}
</style>